package cn.agiledata.bank.transaction.action;

import java.math.BigDecimal;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.common.dao.AccountTemplateInter;
import cn.agiledata.bank.common.dao.TransactionListPage;
import cn.agiledata.bank.common.dao.TransactionTemplate;
import cn.agiledata.bank.common.service.PermissionService;
import cn.agiledata.bank.common.service.SetUpUses;
import cn.agiledata.bank.common.service.email.TransactionEmail;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.ConvertUtil;
import cn.agiledata.bank.common.util.ForeDict;
import cn.agiledata.bank.common.util.PageBean;
import cn.agiledata.bank.common.util.StringUtil;
import cn.agiledata.bank.common.util.UniqueIdentityUtil;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.hibernateBean.TransactionHis;
import cn.agiledata.bank.linkbank.service.WebPayService;
import cn.agiledata.bank.transaction.exception.TransactionException;
import cn.agiledata.bank.transaction.form.ReportForm;
import cn.agiledata.bank.transaction.service.GetTransaction;
import cn.agiledata.bank.transaction.service.GetTransactionImpl;
import cn.agiledata.bank.transaction.service.TransactionFactory;
import cn.agiledata.bank.transaction.service.TransactionService;
import com.vnv.infrastructure.action.IPBBaseAction;
import com.vnv.infrastructure.logic.IPBAppFactory;
import com.vnv.infrastructure.logic.IPBMgrFactory;

public class TransactionList extends IPBBaseAction {
    private static Log logger = LogFactory.getLog(IPBBaseAction.class);
    
    private TransactionService getTransactionService(){
        return (TransactionService)IPBAppFactory.getObj(ForeDict.SERVICE_TRANSACTION);
    }

    public ActionForward preProcess(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        ReportForm reportform = (ReportForm) form;
        reportform.setErrorMsg("");
        TransactionTemplate tt = (TransactionTemplate) IPBMgrFactory
                .getMgr("transactionTemplate");
        AccountTemplateInter at = (AccountTemplateInter) IPBMgrFactory
                .getMgr("accountTemplate");
        long accountId = WeatherUtil.getAccountIdFromSession(request);
        String isIfFinished = request.getParameter("isIfFinished");
        String returnAmount = request.getParameter("returnAmount");
        boolean refresh = true;
        if (!StringUtil.isStrEmpty(isIfFinished)) {
            if (isIfFinished.equals("false")) {
                refresh = false;
            }
        }
        if (!reportform.isIfFinished() || !refresh) {
            String tranId = (String) request.getParameter("tranid");
            String tranStatus = (String) request.getParameter("tranStatus");
            String oldTranStatus = (String) request
                    .getParameter("oldTranStatus");

            if (StringUtils.isNotEmpty(tranId)
                    && StringUtils.isNotEmpty(tranStatus)) {
                Transaction tran = tt.getTransactionByTranId(tranId);

                if (!tran.getTransStatus().equals(oldTranStatus)) {
                    String errorMsg = "对不起，该笔交易的状态已经发生变化，请重新操作!";
                    request.getSession().setAttribute("msg", errorMsg);
                    return mapping.findForward("transMan");
                }

                // 判断当前用户是否具有操作权限
                String permitType = null;
                if (Constant.TRANS_STATUS_APPLYREFUND.equals(tranStatus)) { // 申请退款，判断有无收款权限
                    permitType = Constant.PERMIS_TYPE_GATHERING;
                } else if (Constant.TRANS_STATUS_APPLYREFUNDCLOSE
                        .equals(tranStatus)
                        || Constant.TRANS_STATUS_REFUNDSUCC.equals(tranStatus)
                        || Constant.TRANS_STATUS_TRANSACTIONSUCCESS
                                .equals(tranStatus)) { // 取消退款、同意退款或交易成功，判断有无付款权限
                    permitType = Constant.PERMIS_TYPE_PAYMONEY;
                }
                if (permitType != null
                        && !PermissionService.getPermissionService()
                                .hasPermission(request, permitType)) {
                    String message = getAppExceptionMessage(request,
                            TransactionException.NO_PERMISSION);
                    request.getSession().setAttribute("msg", message);
                    return mapping.findForward("transMan");
                }

                BigDecimal amount = new BigDecimal(tran.getAmount().toString());
                String method = request.getParameter("method");
                if (!StringUtil.isStrEmpty(method)) {
                    request.setAttribute("transAmount", amount.setScale(2));
                    return mapping.findForward(method);
                }
                
                if (Constant.TRANS_STATUS_APPLYREFUND.equals(tranStatus) 
                		&& StringUtils.isNotBlank(returnAmount)) {
                	if (tran.getAmount().doubleValue() - Double.valueOf(returnAmount).doubleValue() < 0){
                		String errorMsg = "对不起，退款金额大于交易金额,请重新操作!";
                        request.getSession().setAttribute("errorMsg", errorMsg);
                        return mapping.findForward("transMan");
                	}
                }

                if (tranStatus.equals(Constant.TRANS_STATUS_APPLYREFUNDCLOSE)) {
                    TransactionHis th = tt.getTransactionHis(tranId);
                    if (th.getTransStatus().equals(
                            Constant.TRANS_STATUS_WAITFORBUYER)
                            && tranStatus
                                    .equals(Constant.TRANS_STATUS_APPLYREFUNDCLOSE)) {
                        tranStatus = Constant.TRANS_STATUS_WAITFORBUYER;
                    }
                    if (th.getTransStatus().equals(
                            Constant.TRANS_STATUS_WAITFORBUYERAFFIRM)
                            && tranStatus
                                    .equals(Constant.TRANS_STATUS_APPLYREFUNDCLOSE)) {
                        tranStatus = Constant.TRANS_STATUS_WAITFORBUYERAFFIRM;
                        //REMARK: RETURN MONGY 取消退款之后 清除掉退款金额字段
                        tran.setReturnAmount(null);
                    }
                }

                GetTransaction getTran = new GetTransactionImpl();

                try {

                    logger.debug("*************       :" + tranStatus
                            + ":             ***************");
                    if (tran == null
                            || (at.compareAccountMoney(tran.getDebit().getId()
                                    .toString(), tran.getAmount()) != 0)
                            && tranStatus
                                    .equals(Constant.TRANS_STATUS_WAITFORBUYERPAY)) {

                        reportform.setErrorMsg("交易操作失败您的交易金额为"
                                + tran.getAmount().doubleValue()
                                + "，\n您或者您的交易对方目前没有足够的资金，请充值后再操作！");

                    } else {
                        String currentAccountId = at.getAccount(
                                String.valueOf(accountId)).getId().toString();
                        Date currentDate = new Date();
                       
                        tran.setTransStatus(tranStatus);

                        if (tran.getTradeType().equals(
                                Constant.TRADE_TYPE_ASSURE)
                                && tran
                                        .getTransStatus()
                                        .equals(
                                                Constant.TRANS_STATUS_TRANSACTIONSUCCESS)) {
                            tran.setOperate(Constant.MODEL_TYPE_GATHERING);
                        }

                        /**
                         * 退款处理，设定为付款，金额为负
                         */
                        if (tran.getTradeType().equals(
                                Constant.TRADE_TYPE_ASSURE)
                                && tran.getTransStatus().equals(
                                        Constant.TRANS_STATUS_REFUNDSUCC)) {
                            tran.setOperate(Constant.MODEL_TYPE_PAYMONEY);
                            tran.setAmount(new Double(-tran.getAmount()
                                    .doubleValue()));
                        }

                        tran.setUpdateTime(currentDate);
                        tran.setUpdateUser(currentAccountId);

                        TransactionFactory tf = getTran
                                .getTransaction(Constant.ACTION_TYPE_C);
                        Account debit = tran.getDebit().getAccount();
                        Account credit = tran.getCredit().getAccount();
                        if (tran.getTransStatus().equals(
                                Constant.TRANS_STATUS_TRANSACTIONSUCCESS)) { // 收货确认
                            if (debit.getAccountType()
                                    .equals(Constant.ACCOUNT_TYPE_CORPORATION)
                                    || credit
                                            .getAccountType()
                                            .equals(
                                                    Constant.ACCOUNT_TYPE_CORPORATION)) {// 付/收款一方是企业
                                tran.setVoucherCode(UniqueIdentityUtil
                                        .getTransferPaperSequence()); // 设置交易回单号
                            }
                        }
                        
                        try {
                            String actionType = tran.getActionType().getId()
                                    .toString();
                            getTransactionService().validateTransactable(debit,
                                    credit, credit.getName(), actionType);
                        } catch (TransactionException e) {
                            String message = getAppExceptionMessage(request, e);
                            request.getSession().setAttribute("msg", message);
                            return mapping.findForward("transMan");
                        }
                        if(Constant.TRANS_STATUS_TRANSACTIONCLOSE.equals(tran.getTransStatus()) ||
                           Constant.TRANS_STATUS_TRANSACTIONSUCCESS.equals(tran.getTransStatus()) ||
                           Constant.TRANS_STATUS_TRANSACTIONFAIL.equals(tran.getTransStatus()) ||
                           Constant.TRANS_STATUS_REFUNDSUCC.equals(tran.getTransStatus())) {//交易状态:交易取消,交易成功,交易失败,退款成功则设置交易结束时间
                        	tran.setEndDate(new Date());
                        }
                        //REMARK : RETURN MONEY 部分退款处理(退款申请)
                        if (Constant.TRANS_STATUS_APPLYREFUND.equals(tranStatus) && StringUtils.isNotBlank(returnAmount)) {
                        	tran.setReturnAmount(Double.valueOf(returnAmount));
                        }
                        tf.saveTransaction(tran);
                        
                        //商户交易向商户发送反馈信息
                        WebPayService webPayService = (WebPayService) IPBAppFactory.getObj(ForeDict.SERVICE_WEB_PAY);
                        webPayService.backgroundResponseByTransId(tran.getTransId());

                        String url = WeatherUtil.getRootFromSession(request);
                        SetUpUses suu = new SetUpUses();

                        if (tran.getTradeType().equals(
                                Constant.TRADE_TYPE_ASSURE)
                                && tran.getTransStatus().equals(
                                        Constant.TRANS_STATUS_REFUNDSUCC)) {
                            /**
                             * 担保交易&退款成功 给买方发邮件
                             */

                            suu.sendSetup(tran, tran.getDebit(),
                                    Constant.MODEL_TYPE_PAYMONEY, tran
                                            .getDebitFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                        } else if (tran.getTradeType().equals(
                                Constant.TRADE_TYPE_ASSURE)
                                && tran.getTransStatus().equals(
                                        Constant.TRANS_STATUS_DISPUTED)) {
                            /**
                             * 担保交易&争议处理 给买方发邮件
                             */
                            suu.sendSetup(tran, tran.getDebit(),
                                    Constant.MODEL_TYPE_PAYMONEY, tran
                                            .getDebitFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                        } else if (tran.getTradeType().equals(
                                Constant.TRADE_TYPE_ASSURE)
                                && tran.getTransStatus().equals(
                                        Constant.TRANS_STATUS_APPLYREFUND)) {
                            /**
                             * 担保交易&退款申请 给卖方发邮件
                             */
                            suu.sendSetup(tran, tran.getCredit(),
                                    Constant.MODEL_TYPE_PAYMONEY, tran
                                            .getDebitFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                            /***************************************************
                             * 买方已付款，等待卖方发货
                             **************************************************/
                        } else if (tran.getTransStatus().equals(
                                Constant.TRANS_STATUS_WAITFORBUYER)) {
                            TransactionEmail tranMail = (TransactionEmail) IPBAppFactory
                                    .getObj("transactionMail");
                            suu.sendSetup(tran, tran.getDebit(),
                                    Constant.MODEL_TYPE_GATHERING, tran
                                            .getCreditFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);

                            suu.sendSetup(tran, tran.getCredit(),
                                    Constant.MODEL_TYPE_GATHERING, tran
                                            .getCreditFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    - tran.getCreditFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                        } else if (tran.getTransStatus().equals(
                                Constant.TRANS_STATUS_WAITFORBUYERAFFIRM)) {
                            suu.sendSetup(tran, tran.getDebit(),
                                    Constant.MODEL_TYPE_GATHERING, tran
                                            .getDebitFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                            suu.sendSetup(tran, tran.getCredit(),
                                    Constant.MODEL_TYPE_GATHERING, tran
                                            .getCreditFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    - tran.getCreditFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                        } else {
                            suu.sendSetup(tran, tran.getDebit(),
                                    Constant.MODEL_TYPE_PAYMONEY, tran
                                            .getDebitFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    + tran.getDebitFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                            suu.sendSetup(tran, tran.getCredit(),
                                    Constant.MODEL_TYPE_GATHERING, tran
                                            .getCreditFee().toString(),
                                    ConvertUtil.parseDec(
                                            new Double(tran.getAmount()
                                                    .doubleValue()
                                                    - tran.getCreditFee()
                                                            .doubleValue()),
                                            "0.00"), url, null);
                        }

                        reportform.setIfFinished(true);
                    }

                } catch (RuntimeException e) {
                    e.printStackTrace();
                }
            }
        }
        int startPage = 1;
        if (reportform.getStartPage() != null
                && !reportform.getStartPage().equals("")) {
            startPage = Integer.parseInt(reportform.getStartPage());
        }
        TransactionListPage pl = new TransactionListPage(startPage, accountId);

        PageBean pb = pl.getAccountListPageBean();

        request.setAttribute("accountList", pb);
        request.setAttribute("ReportForm", reportform);
        if (!StringUtil.isStrEmpty(isIfFinished)) {
            return mapping.findForward("transMan");
        } else {
            return mapping.findForward("transManager");
        }
    }
}